﻿using FreeRedis;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using Simple.Contracts.Contracts;
using Simple.Contracts.Models.Common;
using Simple.Services.Services;
using System.Net;

namespace Simple.WebAi.Authorizes
{
    /// <summary>
    /// 授权验证
    /// </summary>
    public class AccountAuthorizeFilter: IAuthorizationFilter
    {
        private readonly IRedisService _redisService;
        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="redisService"></param>
        public AccountAuthorizeFilter(IRedisService redisService)
        {
            _redisService = redisService;
        }

        /// <summary>
        /// 授权验证
        /// </summary>
        /// <param name="context"></param>
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var accountAuthorizeAttribute = context.ActionDescriptor.FilterDescriptors.Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                .Select(filterDescriptor => filterDescriptor.Filter)
                .OfType<AccountAuthorizeAttribute>().FirstOrDefault();

            // 验证accountAuthorize
            if (accountAuthorizeAttribute == null)
            {
                SetTokenInvalidResult(context);
                return;
            }

            // 验证是否存在token、companyId、employeeId
            if (!context.HttpContext.Request.Headers.ContainsKey("x-access-token") ||
                !context.HttpContext.Request.Headers.ContainsKey("x-access-companyId") ||
                !context.HttpContext.Request.Headers.ContainsKey("x-access-employeeId"))
            {
                SetTokenInvalidResult(context);
                return;
            }

            // 验证token是否有效
            var token = context.HttpContext.Request.Headers["x-access-token"];
            var companyId = long.Parse(context.HttpContext.Request.Headers["x-access-companyId"]!);
            var employeeId = long.Parse(context.HttpContext.Request.Headers["x-access-employeeId"]!);

            var accountJson = _redisService.GetAccountLoginToken(companyId, employeeId, token!);
            if (accountJson == null)
            {
                SetTokenInvalidResult(context);
                return;
            }

            // 验证是否有权限
            var account = JsonConvert.DeserializeObject<CurrentAccount>(accountJson)!;
            var permissions = accountAuthorizeAttribute.Permissions;
            if (permissions != null && permissions.Any())
            {
                if (account.EmployeePermissions == null || account.EmployeePermissions.Count() == 0)
                {
                    SetPermissionDeniedResult(context, permissions);
                    return;
                }
                var commonPermissions = permissions.Intersect(account.EmployeePermissions).ToList();
                if (commonPermissions.Count() == 0)
                {
                    SetPermissionDeniedResult(context, permissions);
                    return;
                }
            }

            SetaccountInfos(context, account);
        }

        /// <summary>
        /// 设置ACCESS_TOKEN 无效
        /// </summary>
        /// <param name="context"></param>
        public void SetTokenInvalidResult(AuthorizationFilterContext context)
        {
            context.Result = new ContentResult
            {
                StatusCode = (int)HttpStatusCode.Unauthorized,
                ContentType = "application/json;charset=utf-8",
                Content = JsonConvert.SerializeObject(Result<string>.FriendlyReminder("您的登录已失效，请重新登录"))
            };
        }

        /// <summary>
        /// 设置无权限
        /// </summary>
        /// <param name="context"></param>
        /// <param name="permissions"></param>
        public void SetPermissionDeniedResult(AuthorizationFilterContext context, string[] permissions)
        {
            context.Result = new ContentResult
            {
                StatusCode = (int)HttpStatusCode.Forbidden,
                ContentType = "application/json;charset=utf-8",
                Content = JsonConvert.SerializeObject(Result<string>.FriendlyReminder("抱歉，您的权限不足"))
            };
        }

        /// <summary>
        /// 设置账号信息
        /// </summary>
        /// <param name="context"></param>
        /// <param name="currentAccount"></param>
        public void SetaccountInfos(AuthorizationFilterContext context, CurrentAccount currentAccount)
        {
            var _currentAccount = (CurrentAccount)context.HttpContext.RequestServices.GetRequiredService(typeof(CurrentAccount))!;

            // 公司信息
            _currentAccount.CompanyId = currentAccount.CompanyId;
            _currentAccount.CompanyName = currentAccount.CompanyName;
            _currentAccount.CompanyVersion = currentAccount.CompanyVersion;
            _currentAccount.CompanyVersionExpiryTime = currentAccount.CompanyVersionExpiryTime;

            // 员工信息
            _currentAccount.EmployeeId = currentAccount.EmployeeId;
            _currentAccount.EmployeeName = currentAccount.EmployeeName;

            // 员工角色及权限
            _currentAccount.EmployeeRoleIds = currentAccount.EmployeeRoleIds;
            _currentAccount.EmployeeIsAdmin = currentAccount.EmployeeIsAdmin;
            _currentAccount.EmployeePermissions = currentAccount.EmployeePermissions;
        }
    }
}
